<?php

namespace addons\cloud_market\controller\api;

use addons\cloud_market\model\CloudMarketAd;
use addons\cloud_market\model\CloudMarketUser;
use hiduoke\controller\AddonsController;
use addons\cloud_market\model\CloudMarketAddon;
use addons\cloud_market\model\CloudMarketAddonVersions;
use addons\cloud_market\model\CloudMarketSite;
use addons\cloud_market\model\CloudMarketSiteAddon;
use addons\cloud_market\model\CloudMarketSiteAddonToken;
use addons\cloud_market\model\CloudMarketProgram;
use addons\cloud_market\model\CloudMarketAddonMinapp;

/**
 * 云端接口统一
 */
class Cloud extends AddonsController
{
    protected $notLogin = ['*'];

    /**
     * @var int 站点ID
     */
    private $site_id;

    /**
     * @var string 站点Token
     */
    private $token;

    /**
     * @var CloudMarketSite 站点信息
     */
    private $siteMsg;

    /**
     * @var string 域名
     */
    private $domain;

    /**
     * 不需要验证的方法
     */
    protected $noCheck = [
        "install",
        "getSystemUpdate",
        "checkApiBySiteToken",
        "checkApiByAddonToken",
        "getTokenByLoginUser",
        "getAddonList",
        "getSiteMsgByLoginUser",
        "getAdList"
    ];

    /**
     * 不拦截
     * @var string[]
     */
    protected $noIntercept = [
        "getSiteAddonTokenCount",
    ];

    protected function initialize()
    {
        parent::initialize();
        global $_DK;
        $_DK['force_json'] = true;
        $noIntercept = !in_array($this->request->action(), $this->noIntercept);
        if (!in_array($this->request->action(), $this->noCheck)) {
            $this->site_id = $this->request->post('site_id') ?: $this->request->header('SiteId');
            $this->token = $this->request->post('token') ?: $this->request->header('Token');
            $this->domain = $this->request->post('domain') ?: $this->request->header('Domain');
            if ((!$this->site_id || !$this->token) && $noIntercept) {
                showMessage("参数错误，站点ID或Token不存在", 'error');
            }
            $site = (new CloudMarketSite())->where(['id' => $this->site_id, 'token' => $this->token])->find();
            if (!$site && $noIntercept) {
                showMessage("没有找到当前站点，请联系售后", 'error');
            }
            if ($site && $site['domain'] != $this->domain && $noIntercept) {
                showMessage('绑定的域名与云端域名不符合，请联系售后');
            }
            $this->siteMsg = $site;
        }
    }

    /**
     * @todo 首页方法
     */
    public function index()
    {
        $data = array(
            "ip"     => getClientIP(),
            "domain" => input('domain')
        );
        return $this->success("", $data);
    }

    /**
     * 获取站点信息
     */
    public function getSiteMsg()
    {
        return $this->success('', $this->siteMsg);
    }

    /**
     * 更新站点信息
     */
    public function updateSite()
    {
        $this->siteMsg->title = input('title', $this->siteMsg->title);
        $this->siteMsg->version = input('version', $this->siteMsg->version);
        $this->siteMsg->corporate_name = input('corporate_name', $this->siteMsg->corporate_name);
        //        $this->siteMsg->phone = input('phone', $this->siteMsg->phone);
        //        $this->siteMsg->qq = input('qq', $this->siteMsg->qq);
        $this->siteMsg->ip = getClientIP();
        $this->siteMsg->save();
        return $this->success('更新成功', ['siteMsg' => $this->siteMsg]);
    }

    /**
     * 获取站点对应的应用
     * @param string $addon_name 应用名称
     */
    public function getSiteAddon($addon_name)
    {
        $addon = (new CloudMarketAddon())->where(['name' => $addon_name])->find();
        if (!$addon) {
            return $this->error('应用不存在');
        }

        $site_addon = (new CloudMarketSiteAddon())->where(['site_id' => $this->site_id, 'addon_id' => $addon['id']])->find();
        if (!$site_addon) {
            return $this->error('当前站点未购买该应用');
        }
        return $this->success('', $site_addon);
    }

    /**
     * 获取当前站点已经购买的应用
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $addon_names string 排除的应用名称
     * @return \think\response\Json
     */
    public function getSiteAddons($addon_names = [])
    {
        $site_addons = (new CloudMarketSiteAddon())
            ->whereNotIn('addon_name', $addon_names)
            ->where(['site_id' => $this->site_id])
            ->append(['addon', 'used_count'])
            ->select();


        return $this->success('', $site_addons);
    }

    /**
     * 获取应用列表 用于后台应用管理-应用市场获取
     * Create by :  刘泓宾<514660094@qq.com>
     */
    public function getAddonList()
    {
        $type = input('type', -1);
        $page = input('page', 1);
        $size = input('size', 7);
        $keyword = input('keyword', '');
        $addon_names = input('addon_names', []);
        $res = (new CloudMarketAddon())
            ->where(function ($query) use ($type, $keyword) {
                if ($type > -1) {
                    $query->where('type', $type);
                }
                if ($keyword) {
                    $query->where('title|description', 'like', "%{$keyword}%");
                }
            })
            ->whereNotIn('name', $addon_names)
            ->where('status', '>', 0)
            ->order('id', 'desc')
            ->page($page)->paginate($size);
        return $this->success('', $res);
    }


    /**
     * 获取站点应用平台次数数组
     * @param array $addon_names 应用名称数组
     */
    public function getSiteAddonsCount($addon_names = [])
    {
        $res = [];
        $addons = CloudMarketSiteAddon::hasWhere('addon', [['name', 'in', $addon_names]], 'count,CloudMarketAddon.name')
            ->where(['site_id' => $this->site_id])->cache(true, 10)
            ->select()->toArray();

        foreach ($addons as $key => $value) {
            $res[$value['name']] = $value['count'];
        }

        return $this->success('', $res);
    }

    /**
     * 获取/生成应用token
     * @param string $addon_name 应用名称
     * @param string $plaid 平台ID
     * @param bool $is_min_app 是否小程序
     */
    public function getSiteAddonToken($addon_name, $plaid, $is_min_app = false)
    {
        $aid = (new CloudMarketAddon())->where(['name' => $addon_name])->value('id');
        if (!$aid) {
            return $this->error('应用不存在', '', -2);
        }

        if ($is_min_app) {
            $row = (new CloudMarketSiteAddonToken());
        } else {
            $row = (new CloudMarketSiteAddonToken())->where([
                'addon_name' => $addon_name,
                'plaid'      => $plaid,
                'site_id'    => $this->site_id
            ])->findOrEmpty();
        }

        if ($row->isEmpty()) {
            $count = (new CloudMarketSiteAddon())->where([
                'site_id'  => $this->site_id,
                'addon_id' => $aid
            ])->value('count');

            $used_count = (new CloudMarketSiteAddonToken())->where([
                'site_id'    => $this->site_id,
                'addon_name' => $addon_name
            ])->count();

            if ($count <= $used_count) {
                return $this->error("token生成失败，应用次数不足");
            }

            $row->aid = $aid;
            $row->site_id = $this->site_id;
            $row->plaid = $plaid;
            $row->addon_name = $addon_name;
            $row->token = md5(md5(time()));
            $row->save();
        }

        return $this->success('', $row);
    }


    /**
     * @param string $addon_name 应用名称
     * @param string $plaid 平台ID
     * @param string $addon_token 应用Token
     * @todo 删除站点应用Token
     */
    public function deleteSiteAddonToken($addon_name, $plaid, $addon_token)
    {
        $site_token = (new CloudMarketSiteAddonToken())->where([
            'token'      => $addon_token,
            'plaid'      => $plaid,
            'addon_name' => $addon_name
        ])->find();

        if (!$site_token) {
            return $this->error('当前应用Token不存在');
        }

        $site_token->delete();
        return $this->success('删除成功');
    }

    /**
     * 检测应用Token
     * @param string $addon_name 应用名称
     * @param string $addon_token 应用Token
     * @param string $plaid 平台ID
     */
    public function checkSiteAddon($addon_name, $addon_token, $plaid = 0)
    {
        $res = (new CloudMarketSiteAddonToken())->where([
            'addon_name' => $addon_name,
            'token'      => $addon_token,
            'plaid'      => $plaid,
            'site_id'    => $this->site_id
        ])->find();
        if ($res) {
            return $this->success('', $res);
        } else {
            return $this->error('无应用信息');
        }
    }

    /**
     * 兼容下面的
     * Create by :  刘泓宾<514660094@qq.com>
     * @return \think\response\Json
     */
    public function getSiteAddonTokenCount2()
    {
        return $this->getSiteAddonTokenCount();
    }

    /**
     * 获取站点应用Token统计 在应用管理中使用
     * Create by :  刘泓宾<514660094@qq.com>
     * @return \think\response\Json
     */
    public function getSiteAddonTokenCount()
    {
        $names = input('names', []);

        // 已使用次数
        $site_addon_token_res = (new CloudMarketSiteAddonToken())
            ->field(['COUNT(`addon_name`) as count', 'addon_name'])
            ->group('addon_name')
            ->where(['site_id' => $this->site_id])
            ->select()
            ->toArray();

        $used_token_count = [];
        foreach ($site_addon_token_res as $key => $value) {
            $used_token_count[$value['addon_name']] = $value['count'];
        }

        // 当前站点存在的应用
        $use_addons = (new CloudMarketAddon())->whereIn('name', $names)->select()->toArray();
        $use_names = array_column($use_addons, 'name');

        // 当前站点购买的应用的总可用次数
        $buy_addons = CloudMarketSiteAddon::hasWhere('addon', '', 'count,CloudMarketAddon.name')
            ->where(['site_id' => $this->site_id])
            ->whereIn("CloudMarketAddon.name", $use_names)
            ->select()->toArray();

        $buy_names = array_column($buy_addons, 'name');
        $res = [];

        foreach ($use_names as $key => $value) {
            $res[$value] = array(
                'state'         => -1,
                'count'         => 0,
                'used_count'    => 0,
                'surplus_count' => 0,
                'site_id'       => $this->site_id
            );
        }

        foreach ($buy_addons as $key => $value) {
            // 站点存在的应用，已购买
            $res[$value['name']] = array(
                'state'         => 0,
                'count'         => $value['count'],
                'used_count'    => $used_token_count[$value['name']] ?? 0,
                'surplus_count' => $value['count'] - ($used_token_count[$value['name']] ?? 0)
            );
        }
        return $this->success("ok", $res);
    }

    /**
     * 获取更新安装包
     */
    public function getUpdateProgram()
    {
        $version = $this->request->post('version', '');
        $program = (new CloudMarketProgram())->getUpdateProgram($version);
        if (!$program || $program->isEmpty()) {
            return $this->error('没有需要更新的安装包');
        }
        $program = array_reverse($program->toArray());
        return $this->success('ok', $program);
    }

    /**
     * @todo 获取程序
     */
    public function getProgram()
    {
        $program = (new CloudMarketProgram())->getProgram(0, '', '', false);
        return $this->success('ok', $program);
    }

    /**
     * 获取应用信息
     * 用于应用安装的时候获取应用信息
     * Create by :  刘泓宾<514660094@qq.com>
     * @return \think\response\Json
     */
    public function getAddonMsg()
    {
        $addon_name = $this->request->post('addon_name', '');
        // TODO 指定版本
        $version = $this->request->post('version', '');
        $checkAddon = (new CloudMarketAddon())->checkAddon($this->site_id, $addon_name);
        if ($checkAddon['code'] == -1) {
            return $this->error($checkAddon['msg']);
        }
        $addon = $checkAddon['data'];
        $addon_version = (new CloudMarketAddonVersions())
            ->where(['aid' => $addon['id'], 'show_switch' => 1])
            ->order('id', 'desc')->find();

        if (!$addon_version) {
            return $this->error('没有可安装的版本');
        }
        $addon['new_version_file'] = cdnurl($addon_version['down_file']);
        $addon['pic_image'] = cdnurl($addon['pic_image']);
        unset($addon['description']);
        $data = $addon;
        $site_addon = (new CloudMarketSiteAddon())->where([
            'site_id'  => $this->site_id,
            'addon_id' => $addon['id']
        ])->find();
        if ($site_addon) {
            // 下载次数
            $site_addon->down_count = $site_addon->down_count + 1;
            // 版本号
            $site_addon->version = $addon_version['version'] ?? '1.0.0';
            $site_addon->save();
            $addon->down_count = $addon->down_count + 1;
            $addon->save();
            return $this->success('ok', $data);
        } else {
            return $this->error('未找到站点信息');
        }
    }


    /**
     * 获取小程序信息
     */
    public function getAddonAppMsg()
    {
        $addon_name = $this->request->post('addon_name', '');
        // 判断站点权限
        $checkAddon = (new CloudMarketAddon())->checkAddon($this->site_id, $addon_name);
        if ($checkAddon['code'] == -1) {
            return $this->error($checkAddon['msg']);
        };
        $addon = $checkAddon['data'];
        $addon_min_app = (new CloudMarketAddonMinapp())->where(['aid' => $addon['id']])
            ->order('id', 'desc')->find();


        if (!$addon_min_app) {
            return $this->error("当前应用没有上传小程序包");
        }

        $addon['new_app_version_file'] = cdnurl($addon_min_app['down_file']);
        $addon['new_app_version'] = $addon_min_app['version'];
        $addon['pic_image'] = cdnurl($addon['pic_image']);
        $addon['change_log'] = $addon_min_app['change_log'] ?: $addon_min_app['version'] . "更新";
        unset($addon['description']);
        unset($addon['labels']);

        return $this->success('ok', $addon);
    }

    /**
     * 获取小程序应用更新信息
     */
    public function getAddonAppUpdateMsg()
    {
        $addon_name = $this->request->post('addon_name', '');
        $version = input('version', '');

        // 判断站点权限
        $checkAddon = (new CloudMarketAddon())->checkAddon($this->site_id, $addon_name);
        if ($checkAddon['code'] == -1) {
            return $this->error($checkAddon['msg']);
        }

        $addon = $checkAddon['data'];
        $where = ['aid' => $addon['id'], 'show_switch' => 1];
        if ($version) {
            $where['version'] = $version;
        }

        $addon_min_app = (new CloudMarketAddonMinapp())->where($where)
            ->order('id', 'desc')->field('name,version,change_log')->find();

        if (!$addon_min_app) {
            return $this->error("当前应用没有上传小程序包");
        }

        return $this->success('ok', $addon_min_app);
    }

    /**
     * 更新站点应用版本
     */
    public function updateSiteAddonVersion()
    {
        $addon_name = $this->request->post('addon_name', '');
        $version = $this->request->post('version', '');

        // 获取应用信息
        $addon = (new CloudMarketAddon())->where(['name' => $addon_name])->find();
        if (!$addon) {
            return $this->error('应用不存在');
        }

        $site_addon = (new CloudMarketSiteAddon())->where([
            'site_id'  => $this->site_id,
            'addon_id' => $addon['id']
        ])->find();

        if (!$site_addon) {
            return $this->error("当前站点没有购买该应用");
        }

        $site_addon->version = $version;
        $site_addon->install = 1;
        $site_addon->save();

        return $this->success('ok');
    }

    /**
     * @todo 更新卸载时间
     */
    public function updateUninstallTime()
    {
        $addon_name = $this->request->post('addon_name', '');

        // 获取应用信息
        $addon = (new CloudMarketAddon())->where(['name' => $addon_name])->find();
        if (!$addon) {
            return $this->error('应用不存在');
        }

        $site_addon = (new CloudMarketSiteAddon())->where([
            'site_id'  => $this->site_id,
            'addon_id' => $addon['id']
        ])->find();

        if (!$site_addon) {
            return $this->error("当前站点没有购买该应用");
        }

        $site_addon->uninstalltime = time();
        $site_addon->install = -1;
        $site_addon->save();

        return $this->success('ok');
    }

    /**
     * 获取应用更新信息
     */
    public function getAddonUpdateMsg()
    {
        $addon_name = $this->request->post('addon_name', '');
        // 指定版本
        $version = input('version', '');
        $checkAddon = (new CloudMarketAddon())->checkAddon($this->site_id, $addon_name);
        if ($checkAddon['code'] == -1) {
            return $this->error($checkAddon['msg']);
        };
        $addon = $checkAddon['data'];
        $where = ['aid' => $addon['id'], 'show_switch' => 1];
        if ($version) {
            $where['version'] = $version;
        }
        $addon_version = (new CloudMarketAddonVersions())->where($where)
            ->field('name,version,content')
            ->order('id', 'desc')
            ->find();
        if (!$addon_version) {
            return $this->error("当前应用没有上传安装包");
        }
        return $this->success('ok', $addon_version);
    }

    /**
     * 通过应用name获取对应最新版本
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $addon_names
     * @return \think\response\Json
     */
    public function getAddonsVersion($addon_names = [])
    {
        $res = [];
        if (is_array($addon_names)) {
            $addons = (new CloudMarketAddon())->whereIn('name', $addon_names)
                ->field(["id", "name"])->select()->append([])->toArray();

            foreach ($addons as $key => $value) {
                $new_version = (new CloudMarketAddonVersions())
                    ->where(['aid' => $value['id'], 'show_switch' => 1])
                    ->order('id', 'desc')
                    ->value('version');

                $res[$value['name']] = $new_version;
            }
        } else {
            return $this->error("addon_names参数为数组");
        }

        return $this->success('', $res);
    }

    /**
     * 获取单个应用最新版本号
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $addon_name
     * @return \think\response\Json
     */
    public function getAddonVersion($addon_name)
    {
        $aid = (new CloudMarketAddon())->where('name', $addon_name)->value('id');

        $version = (new CloudMarketAddonVersions())
            ->where(['aid' => $aid, 'show_switch' => 1])
            ->order('id', 'desc')
            ->value('version');

        return $this->success('', ['new_version' => $version]);
    }

    /**
     * 获取系统更新列表[当前用于vue2版本文档展示]
     * Create by :  刘泓宾<514660094@qq.com>
     * @return \think\response\Json
     */
    public function getSystemUpdate()
    {
        $page = input('page', 0);
        $updates = (new CloudMarketProgram())->order('id', 'desc')
            ->limit($page, 10)->hidden(['down_file'])->select();

        foreach ($updates as $key => $value) {
            $updates[$key]['updatetime'] = date("Y-m-d", $value['updatetime']);
        }

        return $this->success('ok', $updates);
    }

    /**
     * 获取登录用户信息
     * Create by :  刘泓宾<514660094@qq.com>
     * @return \think\response\Json
     */
    public function getTokenByLoginUser()
    {
        $account = input('account', '');
        $password = input('password', '');
        if ($this->auth->login($account, $password) && !$this->auth->getError()) {
            // 系统本身用户
            $systemUserinfo = $this->auth->getUserinfo();
            $user = (new CloudMarketUser())->where(['uid' => $systemUserinfo['uid']])->find();
            $ip = $this->request->ip();
            $user->loginip = $ip;
            $user->save();
            return $this->success("登录成功", ['token' => $this->auth->getToken(), 'userinfo' => $user]);
        } else {
            return $this->error($this->auth->getError());
        }
    }

    /**
     * 获取站点信息通过当前域名
     * Create by :  刘泓宾<514660094@qq.com>
     */
    public function getSiteMsgByLoginUser()
    {
        $bind_domain = input('bind_domain', '');

        //        $bind_domain = "duokeshop.xyz";

        // 校验域名合法性
        if (!$this->validateDomain($bind_domain)) {
            return $this->error("禁止绑定本地地址或非法域名");
        }
        $account = input('account', '');
        $password = input('password', '');
        if ($this->auth->login($account, $password) && !$this->auth->getError()) {
            // 系统本身用户
            $systemUserinfo = $this->auth->getUserinfo();
            $user = (new CloudMarketUser())->where(['uid' => $systemUserinfo['uid']])->find();
            // 站点信息
            $site = (new CloudMarketSite())->where(['domain' => $bind_domain])->find();

            if ($site && $site['user_id'] != $user['id']) {
                return $this->error("当前站点不属于当前用户");
            }
            if (!$site) {
                // 创建站点
                $data = array(
                    'title'   => '',
                    'user_id' => $user['id'],
                    'domain'  => $bind_domain,
                    'version' => input('version', ''),
                    'ip'      => getClientIP(),
                    'status'  => 0,
                    'type'    => 0,
                    'token'   => md5(md5($bind_domain . $user['id'] . time())),
                    'level'   => 0
                );
                $site = (new CloudMarketSite());
                $site->save($data);
            }
            return $this->success('ok', $site);
        } else {
            return $this->error($this->auth->getError());
        }
    }

    // 获取产品动态
    public function getAdList($status, $count)
    {
        $ads = (new CloudMarketAd())->where(['status' => $status])->limit($count)->select();
        return $this->success('', $ads);
    }

    /**
     * 验证域名合法性
     * @param string $domain
     * @return bool
     */
    protected function validateDomain($domain)
    {
        // 空值检查
        if (empty($domain)) {
            return false;
        }

        // 常规域名正则 (包含国际化域名)
        $pattern = '/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i';

        // 排除以下非法情况:
        // 1. 本地地址 (localhost)
        // 2. IP地址 (IPv4/IPv6)
        // 3. 内网地址 (192.168., 10., 172.16.~172.31.)
        // 4. 非标准域名 (包含下划线等非法字符)
        $forbidden = [
            'localhost',
            '127.0.0.1',
            '0.0.0.0',
            '192.168.',
            '10.',
            '172.16.',
            '172.17.',
            '172.18.',
            '172.19.',
            '172.20.',
            '172.21.',
            '172.22.',
            '172.23.',
            '172.24.',
            '172.25.',
            '172.26.',
            '172.27.',
            '172.28.',
            '172.29.',
            '172.30.',
            '172.31.',
            '[::1]' // IPv6本地地址
        ];

        // 检查是否匹配禁止规则
        foreach ($forbidden as $item) {
            if (strpos($domain, $item) === 0) {
                return false;
            }
        }

        // 验证标准域名格式
        if (!preg_match($pattern, $domain)) {
            // 如果是IP地址直接拒绝
            if (filter_var($domain, FILTER_VALIDATE_IP)) {
                return false;
            }
            return false;
        }

        return true;
    }

    /**
     * @param int $dk_pid 接口ID
     * @param int $site_id 站点ID
     * @param string $site_token 站点Token
     * @todo 检查API通过站点Token【废除】
     */
    public function checkApiBySiteToken($dk_pid = 0, $site_id = 0, $site_token = '')
    {
        // 这部分功能可能需要根据您的API系统进行调整
        return $this->success('功能待实现');
    }

    /**
     * @todo 检查API通过应用Token【废除】
     */
    public function checkApiByAddonToken()
    {
        // 这部分功能可能需要根据您的API系统进行调整
        return $this->success('功能待实现');
    }
}
